package com.spring.shiro.web;

import com.spring.shiro.common.Log;
import com.spring.shiro.common.controller.BaseController;
import com.spring.shiro.entity.User;
import com.spring.shiro.qo.QueryRequest;
import com.spring.shiro.service.UserService;
import com.spring.shiro.utils.FileUtil;
import com.spring.shiro.utils.MD5Utils;
import com.spring.shiro.utils.ResponseBo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

@Api(value = "用户Controller", tags = {"用户Controller"})
@Slf4j
@Controller
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @PostMapping("/user")
    @RequiresPermissions("user:list")
    @ApiIgnore
    public String index(Model model) {
        User user = super.getCurrentUser();
        model.addAttribute("user", user);
        return "system/user/user";
    }

    @PostMapping("/user/regist")
    @ResponseBody
    @ApiOperation(value = "注册用户", notes = "注册用户")
    public ResponseBo regist(User user) {
        try {
            User result = this.userService.findByName(user.getUsername());
            if (result != null) {
                return ResponseBo.warn("该用户名已被使用！");
            }
            this.userService.registUser(user);
            return ResponseBo.ok();
        } catch (Exception e) {
            log.error("注册失败", e);
            return ResponseBo.error("注册失败，请联系网站管理员！");
        }
    }

    @Log("获取用户信息")
    @GetMapping("/user/list")
    @RequiresPermissions("user:list")
    @ResponseBody
    @ApiOperation(value = "用户管理列表", notes = "用户管理列表")
    public Map<String, Object> userList(QueryRequest request, User user) {
        return super.selectByPageNumSize(request, () -> this.userService.findUserWithDept(user, request));
    }

    @PostMapping("/user/getUser")
    @ResponseBody
    @ApiOperation(value = "获取用户信息（修改前调用）", notes = "获取用户信息")
    public ResponseBo getUser(@ApiParam(value = "用户Id", required = true) @RequestParam Long userId) {
        try {
            User user = this.userService.findById(userId);
            return ResponseBo.ok(user);
        } catch (Exception e) {
            log.error("获取用户失败", e);
            return ResponseBo.error("获取用户失败，请联系网站管理员！");
        }
    }

    @GetMapping("/user/checkUserName")
    @ResponseBody
    @ApiOperation(value = "验证用户名是否可用（新增用户前调用 false表示不可用，该用户名已存在，true表示可用）", notes = "验证用户名是否存在")
    public boolean checkUserName(@ApiParam(value = "用户名", required = true)@RequestParam String username,
                                 @ApiParam(value = "旧用户名，修改验证，新增不用传")@RequestParam String oldusername) {
        if (StringUtils.isNotBlank(oldusername) && username.equalsIgnoreCase(oldusername)) {
            return true;
        }
        User result = this.userService.findByName(username);
        return result == null;
    }

    @Log("新增用户")
    @RequiresPermissions("user:add")
    @PostMapping("user/add")
    @ResponseBody
    @ApiOperation(value = "新增用户", notes = "新增用户")
    public ResponseBo addUser(@Valid User user, @ApiParam(value = "角色Id数组") @RequestParam Long[] roles) {
        try {
            if ("on".equalsIgnoreCase(user.getStatus()))
                user.setStatus(User.STATUS_VALID);
            else
                user.setStatus(User.STATUS_LOCK);
            this.userService.addUser(user, roles);
            return ResponseBo.ok("新增用户成功！");
        } catch (Exception e) {
            log.error("新增用户失败", e);
            return ResponseBo.error("新增用户失败，请联系网站管理员！");
        }
    }

    @Log("修改用户")
    @RequiresPermissions("user:update")
    @PostMapping("/user/update")
    @ResponseBody
    @ApiOperation(value = "修改用户", notes = "修改用户")
    public ResponseBo updateUser(@Valid User user,@ApiParam(value = "角色Id数组") @RequestParam Long[] rolesSelect) {
        try {
            if ("on".equalsIgnoreCase(user.getStatus()))
                user.setStatus(User.STATUS_VALID);
            else
                user.setStatus(User.STATUS_LOCK);
            this.userService.updateUser(user, rolesSelect);
            return ResponseBo.ok("修改用户成功！");
        } catch (Exception e) {
            log.error("修改用户失败", e);
            return ResponseBo.error("修改用户失败，请联系网站管理员！");
        }
    }

    @Log("删除用户")
    @RequiresPermissions("user:delete")
    @PostMapping("user/delete")
    @ResponseBody
    @ApiOperation(value = "删除用户成功", notes = "删除用户成功")
    public ResponseBo deleteUsers(@ApiParam(value = "用户id，多个用户ID用,隔开", required = true) @RequestParam String ids) {
        try {
            this.userService.deleteUsers(ids);
            return ResponseBo.ok("删除用户成功！");
        } catch (Exception e) {
            log.error("删除用户失败", e);
            return ResponseBo.error("删除用户失败，请联系网站管理员！");
        }
    }

    @GetMapping("/user/checkPassword")
    @ResponseBody
    @ApiOperation(value = "验证原密码是否正确", notes = "验证原密码是否正确")
    public boolean checkPassword(@ApiParam(value = "原密码", required = true) @RequestParam String password) {
        User user = getCurrentUser();
        String encrypt = MD5Utils.encrypt(user.getUsername().toLowerCase(), password);
        return user.getPassword().equals(encrypt);
    }

    @PostMapping("/user/updatePassword")
    @ResponseBody
    @ApiOperation(value = "修改密码", notes = "修改密码")
    public ResponseBo updatePassword(@ApiParam(value = "新密码", required = true) @RequestParam String newPassword) {
        try {
            this.userService.updatePassword(newPassword);
            return ResponseBo.ok("更改密码成功！");
        } catch (Exception e) {
            log.error("修改密码失败", e);
            return ResponseBo.error("更改密码失败！");
        }
    }

    @PostMapping("/user/excel")
    @ResponseBody
    public ResponseBo userExcel(User user) {
        try {
            List<User> list = this.userService.findUserWithDept(user, null);
            return FileUtil.createExcelByPOIKit("用户表", list, User.class);
        } catch (Exception e) {
            log.error("导出用户信息Excel失败", e);
            return ResponseBo.error("导出Excel失败，请联系网站管理员！");
        }
    }

}
